package core;

import java.util.ArrayList;
import java.util.Vector;

public class Administrator {
	private static final int MIN_MOBS = 2;
	private static final int MIN_POTIONS = 2;
	private static final int TURNS = 3;
	private int time;
	private Player player;
	private Prison prison;
	private ArrayList<Monster> monsters = new ArrayList<Monster>();

	public Administrator() {
		intInitiate();
	}

	public Administrator(int entrance, int exit, Vector<Integer> wall,
			int longSide, int shortSide, int playerPos, int hp, int maxHp,
			int time, Vector<Integer> monsters, Vector<Integer> potions) {
		intLoad(entrance, exit, wall, longSide, shortSide, playerPos, hp,
				maxHp, time, monsters, potions);
	}

	public boolean playerMove(char c) {
		return intPlayerMove(c);
	}

	public void moveMobs() {
		intMoveMobs();
	}

	public boolean clearMobs() {
		return intClearMobs();
	}

	public void time() {
		intTime();
	}

	public boolean checkFinish() {
		return intCheckFinish();
	}

	public Room getCurrentRoom() {
		return prison.getRoom();
	}

	public Player getPlayer() {
		return player;
	}

	public int getTime() {
		return time;
	}

	private void intInitiate() {
		this.prison = new Prison();
		/* Place the player at the entrance */
		this.player = new Player(prison.getRoom());

		this.time = 0;

		/* Create mobs and place them */
		for (int i = 0; i < MIN_MOBS; i++) {
			this.monsters.add(new Monster(prison.getRoom()));
		}

		/* Create potions and place them */
		for (int i = 0; i < MIN_POTIONS; i++) {
			new Potion(prison.getRoom());
		}
	}

	private void intLoad(int entrance, int exit, Vector<Integer> wall,
			int longSide, int shortSide, int playerPos, int hp, int maxHp,
			int time, Vector<Integer> monsters, Vector<Integer> potions) {
		this.prison = intLoadPrison(intLoadRoom(intLoadEntrance(entrance),
				intLoadExit(exit), intLoadWall(wall), longSide, shortSide));
		this.player = intLoadPlayer(playerPos, hp, maxHp);
		this.prison.getRoom().addElement(player);
		this.time = time;
		for (int i = 0; i < monsters.size(); i++) {
			Monster m = new Monster(monsters.get(i));
			this.monsters.add(m);
			prison.getRoom().addElement(m);
		}
		for (int i = 0; i < potions.size(); i++) {
			Potion p = new Potion(potions.get(i));
			prison.getRoom().addElement(p);
		}
	}

	private ArrayList<Wall> intLoadWall(Vector<Integer> wall) {
		ArrayList<Wall> limits = new ArrayList<Wall>();
		for (int i = 0; i < wall.size(); i++)
			limits.add(new Wall(wall.get(i)));
		return limits;
	}

	private Entrance intLoadEntrance(int pos) {
		return new Entrance(pos);
	}

	private Exit intLoadExit(int pos) {
		return new Exit(pos);
	}

	private Room intLoadRoom(Entrance entrance, Exit exit,
			ArrayList<Wall> limits, int longSide, int shortSide) {
		return new Room(entrance, exit, limits, longSide, shortSide);
	}

	private Prison intLoadPrison(Room room) {
		return new Prison(room.getEntrance(), room.getExit(), room.getLimits(),
				room.getLongSide(), room.getShortSide());
	}

	private Player intLoadPlayer(int pos, int hp, int maxHp) {
		return new Player(pos, hp, maxHp);
	}

	private boolean intPlayerMove(char c) {
		return (player.move(c, prison.getRoom()));
	}

	private void intMoveMobs() {
		/* Move each monster */
		for (Monster m : monsters)
			m.selfMovement(prison.getRoom());
	}

	private boolean intClearMobs() {
		ArrayList<Monster> deleteMonsters = new ArrayList<Monster>();
		/* Need to check if mob died */
		for (Monster m : monsters)
			if (m.getHp() == 0)
				deleteMonsters.add(m);
		for (Monster m : deleteMonsters)
			monsters.remove(m);
		if (deleteMonsters.size() > 0)
			return true;
		return false;
	}

	private void intTime() {
		/* The player levels up every TURNS turns */
		time++;
		if (player.getHp() != 0)
			if (time % TURNS == 0)
				player.levelUp();
	}

	private boolean intCheckFinish() {
		if ((player.getHp() == 0)
				|| (player.getPos() == prison.getRoom().getExit().getPos()))
			return true;
		return false;
	}
}
